/**
 * @file   encode_detail.hpp
 * @author wolfhead <wolfhead@wolfhead-laptop>
 * @date   Fri Aug 26 09:38:54 2011
 * 
 * @brief  
 * 
 * 
 */
#ifndef ACAPELLA_ENCODE_DETAIL_HPP
#define ACAPELLA_ENCODE_DETAIL_HPP

#include <string>

namespace acapella
{
namespace __detail__
{

template<typename CharType>
struct __charset_traits
{
};

template<>
struct __charset_traits<char>
{
    typedef char            value_type;
    typedef char *          pointer_type;
    typedef const char *    const_pointer_type;
    typedef char &          reference_type;
    typedef std::string     string_type;

    static inline size_t strlen(const_pointer_type str)
    {
        return ::strlen(str);
    }
};

template<>
struct __charset_traits<wchar_t>
{
    typedef wchar_t         value_type;
    typedef wchar_t*        pointer_type;
    typedef const wchar_t * const_pointer_type;
    typedef wchar_t &       reference_type;
    typedef std::wstring    string_type;

    static inline size_t strlen(const_pointer_type str)
    {
        return ::wcslen(str);
    }
};

template<typename CharType>
struct _charset
{
    typedef __charset_traits<CharType> traits;
};


struct __UrlEncoding
{
    static inline bool isUrlCharacter(unsigned char c)
    {
        /**
         * Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()"
         * and reserve characters used for their reserved purpose may be used
         * unencoded within a URL
         */

#ifdef  _0_
#error  "_0_ already defined"
#else
#define _0_ (0)
        static const unsigned char map[256] = {
            //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
            /* 0 */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* 1 */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* 2 */ _0_,'!',_0_,_0_,'$',_0_,_0_,_0_,_0_,_0_,'*','+',_0_,'-','.',_0_,
            /* 3 */ '0', 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,'9',_0_,_0_,_0_,_0_,_0_,_0_,
            /* 4 */ _0_,'A', 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
            /* 5 */  1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,'Z',_0_,_0_,_0_,_0_,'_',
            /* 6 */ _0_,'a', 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
            /* 7 */  1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,'z',_0_,_0_,_0_,_0_,_0_,
            /* 8 */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* 9 */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* A */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* B */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* C */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* D */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* E */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,
            /* F */ _0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_,_0_
        };
#undef _0_
#endif //#ifdef  _0_

        return map[c];
    }
};


}//namespace __detail__
}//namespace acapella

#endif
